from datetime import datetime
import time
from abc import ABC, abstractmethod

from fastapi_pagination.bases import AbstractPage
from fastapi_pagination.ext.databases import paginate
from sqlalchemy import insert, select, update

from forward.api.admin.schemas.channel import (
    ChannelOaReplyKeywordCreateInSchema,
    ChannelOaReplyKeywordEditInSchema,
    ChannelOaReplyOutSchema,
)
from forward.dependencies.database import db
from forward.model.tables import OfficialReplyModel


class ChannelOaReplyKeywordService:
    """公众号关键词回复服务实现类"""

    async def list(self) -> AbstractPage[ChannelOaReplyOutSchema]:
        """关键词回复列表"""
        query = (
            select(OfficialReplyModel)
            .where(
                OfficialReplyModel.reply_type == 2, OfficialReplyModel.is_delete == 0
            )
            .order_by(OfficialReplyModel.sort.desc(), OfficialReplyModel.id.desc())
        )
        return await paginate(db, query)

    async def detail(self, id_: int) -> ChannelOaReplyOutSchema:
        """关键词回复详情"""
        reply = await db.fetch_one(
            select(OfficialReplyModel).where(
                OfficialReplyModel.id == id_,
                OfficialReplyModel.reply_type == 2,
                OfficialReplyModel.is_delete == 0,
            )
        )
        assert reply, "关键词回复数据不存在!"
        return ChannelOaReplyOutSchema.model_validate(reply, from_attributes=True)

    async def add(self, create_in: ChannelOaReplyKeywordCreateInSchema):
        """关键词回复新增"""
        create_dict = create_in.model_dump()
        create_dict["reply_type"] = 2

        await db.execute(insert(OfficialReplyModel).values(**create_dict))

    @db.transaction()
    async def edit(self, edit_in: ChannelOaReplyKeywordEditInSchema):
        """关键词回复编辑"""
        reply = await db.fetch_one(
            select(OfficialReplyModel).where(
                OfficialReplyModel.id == edit_in.id,
                OfficialReplyModel.reply_type == 2,
                OfficialReplyModel.is_delete == 0,
            )
        )
        assert reply, "关键词回复数据不存在!"
        edit_dict = edit_in.model_dump()
        edit_dict["reply_type"] = 2
        await db.execute(
            update(OfficialReplyModel)
            .where(OfficialReplyModel.id == edit_in.id)
            .values(**edit_dict)
        )

    async def delete(self, id_: int):
        """关键词回复删除"""
        reply = await db.fetch_one(
            select(OfficialReplyModel).where(
                OfficialReplyModel.id == id_,
                OfficialReplyModel.reply_type == 2,
                OfficialReplyModel.is_delete == 0,
            )
        )
        assert reply, "关键词回复数据不存在!"
        await db.execute(
            update(OfficialReplyModel)
            .where(OfficialReplyModel.id == id_)
            .values({"is_delete": 1, "deleted_time": datetime.now()})
        )

    async def status(self, id_: int):
        """关键词回复状态"""
        reply_record = await db.fetch_one(
            select(OfficialReplyModel).where(
                OfficialReplyModel.id == id_,
                OfficialReplyModel.reply_type == 2,
                OfficialReplyModel.is_delete == 0,
            )
        )
        assert reply_record, "关键词回复数据不存在!"
        reply = ChannelOaReplyOutSchema.model_validate(
            reply_record, from_attributes=True
        )
        status = 0 if reply.status else 1
        await db.execute(
            update(OfficialReplyModel)
            .where(OfficialReplyModel.id == id_)
            .values({"status": status})
        )

    @classmethod
    async def instance(cls):
        """实例化"""
        return cls()
